package sys

import (
	"ginweb-admin/commons/base/api"
	"ginweb-admin/commons/response"
	"ginweb-admin/model/commons/request"
	resp "ginweb-admin/model/commons/response"
	"ginweb-admin/model/context"
	"ginweb-admin/model/entity/sys"
	"ginweb-admin/utils"
	"github.com/gin-gonic/gin"
	"github.com/gookit/validate"
	"strings"
)

type SysUserApi struct {
	api.BaseApi
}

// 管理员修改密码
func (api *SysUserApi) UpdatePwd(c *gin.Context) {
	// 准备接收数据的载体
	sysUserPwdContext := context.SysUserPwdContext{}
	// 绑定数据
	err := c.ShouldBindJSON(&sysUserPwdContext)
	if err != nil {
		response.FailWithError(err, c)
		return
	}
	// 参数校验
	validation := validate.Struct(&sysUserPwdContext)
	if !validation.Validate() {
		response.FailWithValidatorData(validation, c)
		return
	}

	// 判断用户两次输入的密码是否一致
	if sysUserPwdContext.Password != sysUserPwdContext.ConfirmPassword {
		response.FailWithMessage("密码或确认密码不一致！", c)
		return
	}

	// 获取用户的id
	sysUser, err := sysUserService.GetById(sysUserPwdContext.UserId)
	// 判断用户id是否存在
	if sysUser.ID != sysUserPwdContext.UserId {
		response.FailWithMessage("操作的用户不存在！", c)
		return
	}

	// 指定更新用户密码
	newSysUser := sys.SysUser{}
	newSysUser.ID = sysUser.ID
	newSysUser.Slat = utils.GetUUID()
	newSysUser.Password = utils.Md5Slat(sysUserPwdContext.Password, newSysUser.Slat)

	// 调用修改密码的方法
	sysUserService.UpdateSysUserPwd(&newSysUser)
	response.OkMessage("密码修改成功", c)
}

// 用户修改自己的密码
func (api *SysUserApi) UpdatePwdSelf(c *gin.Context) {
	// 准备接收数据的载体
	UserPwdContext := context.UserPwdContext{}
	// 绑定数据
	err := c.ShouldBindJSON(&UserPwdContext)
	if err != nil {
		response.FailWithError(err, c)
		return
	}
	// 参数校验
	validation := validate.Struct(&UserPwdContext)
	if !validation.Validate() {
		response.FailWithValidatorData(validation, c)
		return
	}

	// 判断用户两次输入的密码是否一致
	if UserPwdContext.Password != UserPwdContext.ConfirmPassword {
		response.FailWithMessage("密码或确认密码不一致！", c)
		return
	}

	// 获取用户登录时的id
	sysUser, err := sysUserService.GetById(api.GetLoginUserId(c))
	if sysUser.ID == 0 {
		response.FailWithMessage("操作的用户不存在！", c)
		return
	}

	// 指定更新用户密码
	newSysUser := sys.SysUser{}
	newSysUser.ID = sysUser.ID
	newSysUser.Slat = utils.GetUUID()
	newSysUser.Password = utils.Md5Slat(UserPwdContext.Password, newSysUser.Slat)

	// 调用修改密码的方法
	sysUserService.UpdateSysUserPwd(&newSysUser)
	response.OkMessage("密码修改成功", c)
}

// 保存系统用户信息
func (api *SysUserApi) SaveData(c *gin.Context) {
	// 准备数据的载体
	sysUserContext := context.SysUserContext{}
	// 绑定数据
	err := c.ShouldBindJSON(&sysUserContext)
	if err != nil {
		// 如果参数注入失败或者出错就返回
		response.FailWithBindParams(c)
		return
	}
	// 验证绑定的数据
	validation := validate.Struct(&sysUserContext)
	if !validation.Validate() {
		response.FailWithValidatorData(validation, c)
		return
	}

	// 判断当前账号是否已存在
	exitSysUser := sysUserService.LoginAccountAndPhoneAndNickname(sysUserContext.Account)
	if exitSysUser != nil {
		response.FailWithMessage("用户账号已存在！", c)
		return
	}

	// 创建模型实例
	sysUser := sys.SysUser{}
	// 对象复制
	utils.CopyProperties(&sysUser, sysUserContext)
	// 设置uuid
	sysUser.UUID = utils.GetUUID()
	// 设置密码盐
	sysUser.Slat = utils.GetUUID()
	// 密码加密
	sysUser.Password = utils.Md5Slat(sysUser.Password, sysUser.Slat)
	// 保存系统用户
	err = sysUserService.SaveData(&sysUser)
	if err != nil {
		response.FailWithMessage("系统用户创建失败", c)
		return
	}
	// 如果保存成功，就返回创建创建成功
	response.Ok("创建成功", c)
}

// 修改系统用户信息
func (api *SysUserApi) UpdateData(c *gin.Context) {
	// 获取用户传递的参数
	var sysUser sys.SysUser
	// 绑定参数
	err := c.ShouldBindJSON(&sysUser)
	if err != nil {
		response.FailWithError(err, c)
		return
	}
	// 结构体转化成map呢？
	// m := structs.Map(sysUser)
	// 继承的结构体无法转换，要么手动添加，要么不使用继承
	// m["is_deleted"] = sysUser.IsDeleted

	// 嵌套结构体转map
	m := utils.StructToMap(sysUser)
	// 调用更新的方法
	err = sysUserService.UpdateData(&sysUser, &m)
	if err != nil {
		response.FailWithMessage("更新失败！", c)
		return
	}
	response.OkMessage("更新成功！", c)
}

// 修改系统用户状态
func (api *SysUserApi) UpdateStatus(c *gin.Context) {
	// 获取请求的结构体
	sysUserStatus := context.StatusContext{}
	// 绑定参数
	err := c.ShouldBindJSON(&sysUserStatus)
	if err != nil {
		// 如果参数注入失败或者出错就返回
		response.FailWithBindParams(c)
		return
	}

	// 调用修改状态的方法
	err = sysUserService.UpdateStatus(sysUserStatus)
	if err != nil {
		response.FailWithMessage("状态更新失败！", c)
		return
	}

	response.OkMessage("状态更新成功！", c)

}

// 单个删除系统用户信息
func (api *SysUserApi) DeleteById(c *gin.Context) {
	// 获取用户传递的参数id
	id := c.Param("id")
	// 调用删除方法
	err := sysUserService.UnDeleteById(api.StringToUnit(id))
	if err != nil {
		response.FailWithMessage("删除失败！", c)
		return
	}
	// 返回成功
	response.OkMessage("删除成功！", c)
}

// 批量删除系统用户信息
func (api *SysUserApi) DeleteIds(c *gin.Context) {
	// 获取用户删除的ids  例如：ids = 1,2,3
	ids := c.Query("ids")
	// 根据，拆分 获取到具体的id
	idStrings := strings.Split(ids, ",")

	// 定义存储id数据的容器
	var sysUsers []*sys.SysUser
	for _, id := range idStrings {
		// 定义存放每条id数据的容器
		sysUser := sys.SysUser{}
		// 字符串转换成数字类型
		sysUser.ID = api.StringToUnit(id)
		// 把每条id的数据存放到切片类型的容器中
		sysUsers = append(sysUsers, &sysUser)
	}

	// 调用删除方法
	err := sysUserService.UnDeleteByIds(sysUsers)
	if err != nil {
		response.FailWithMessage("批量删除失败！", c)
		return
	}
	response.OkMessage("批量删除成功！", c)

}

// 根据id查询系统用户信息
func (api *SysUserApi) GetById(c *gin.Context) {
	// 获取用户传递的id
	id := c.Param("id")
	// 调用查询的方法
	sysUser, err := sysUserService.GetById(api.StringToUnit(id))
	if err != nil {
		response.FailWithMessage("查询的用户不存在！", c)
		return
	}
	response.Ok(sysUser, c)

}

// 分页查询系统用户信息
func (api *SysUserApi) LoadPage(c *gin.Context) {
	// 创建分页对象
	pageInfo := request.PageInfo{}
	// 绑定参数
	err := c.ShouldBindJSON(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 调用查询分页的方法
	sysUserPage, total, err := sysUserService.LoadPage(pageInfo)
	if err != nil {
		response.FailWithMessage("获取失败"+err.Error(), c)
		return
	}

	response.Ok(resp.PageResult{
		List:     sysUserPage,
		Total:    total,
		Page:     pageInfo.Page,
		PageSize: pageInfo.PageSize,
	}, c)
}
